using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Linq;
using System.Data.Linq.Mapping;

namespace ClubWebsite
{
    public partial class UserConfirmRegistration : System.Web.UI.UserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                // Enter QueryString parameters into the controls if they're provided
                if (Request.QueryString["Email"] != null)
                {
                    txtEmail.Text = HttpUtility.HtmlDecode(Request.QueryString["Email"].Trim());
                }
                if (Request.QueryString["ConfirmationCode"] != null)
                {
                    txtConfirmationCode.Text = Request.QueryString["ConfirmationCode"].Trim();
                }

                // Attempt to validate the confirmation code if all necessary information is provided
                if ((txtEmail.Text.Trim().Length > 0) && (txtConfirmationCode.Text.Trim().Length > 0))
                {
                    btnOK_Click(this, EventArgs.Empty);
                }

                // Display the 'enter confirmation code' controls unless the user
                // is logged in
                if (!HttpContext.Current.User.Identity.IsAuthenticated)
                {
                    pnlEnterConfirmationCode.Visible = true;
                    pnlLoggedIn.Visible = false;
                }
                else
                {
                    pnlEnterConfirmationCode.Visible = false;
                    pnlLoggedIn.Visible = true;
                }
            }
        }

        protected void btnOK_Click(object sender, EventArgs e)
        {
            // Validation
            lblEmailError.Visible = false;
            lblConfirmationCodeError.Visible = false;
            lblInformation.Visible = false;
            if ((!EmailIsValid()) | (!ConfirmationCodeIsValid()))
            {
                return;
            }

            using (MainDataClassesDataContext databaseDataContext = Functions.GetDatabaseDataContext())
            {
                // Check that the validation code is valid
                User user = databaseDataContext
                    .Users
                    .Where(u => (u.Email.ToLower() == txtEmail.Text.Trim().ToLower()) && (u.EmailConfirmationCode.ToLower() == txtConfirmationCode.Text.Trim().ToLower()))
                    .Select(u => u)
                    .FirstOrDefault();
                if (user == null)
                {
                    lblConfirmationCodeError.Text = "The confirmation code is incorrect";
                    lblConfirmationCodeError.Visible = true;
                    return;
                }

                // Accept the confirmation code
                user.EmailConfirmed = 1;
                databaseDataContext.SubmitChanges();

                // Log the user in
                FormsAuthentication.SetAuthCookie(user.ID.ToString(), false);

                // Refresh the page as this will inform the user that the confirmation
                // code has been accepted
                Response.Redirect("../confirmregistration/");
            }
        }

        private bool EmailIsValid()
        {
            // Required
            if (txtEmail.Text.Trim().Length == 0)
            {
                lblEmailError.Text = "An entry is required";
                lblEmailError.Visible = true;
                return false;
            }

            // Max length
            int maxLength = typeof(User).GetProperties()
                .Where(p => p.Name.ToLower() == "email")
                .Select(p => Functions.GetColumnSize((ColumnAttribute)p.GetCustomAttributes(typeof(ColumnAttribute), false).First()))
                .First();
            if (txtEmail.Text.Trim().Length > maxLength)
            {
                lblEmailError.Text = String.Format("The entry cannot be more than {0} characters", maxLength);
                lblEmailError.Visible = true;
                return false;
            }

            using (MainDataClassesDataContext databaseDataContext = Functions.GetDatabaseDataContext())
            {
                // Doesn't exist
                Guid userID = databaseDataContext
                    .Users
                    .Where(u => u.Email.ToLower() == txtEmail.Text.Trim().ToLower())
                    .Select(u => u.ID)
                    .FirstOrDefault();
                if (userID == Guid.Empty)
                {
                    lblEmailError.Text = "Email address has not been registered on this website";
                    lblEmailError.Visible = true;
                    return false;
                }

                // Email already confirmed
                bool emailConfirmed = databaseDataContext
                     .Users
                     .Any(u => (u.ID == userID)
                         && (u.EmailConfirmed != null)
                         && ((byte)u.EmailConfirmed) != 0);
                if (emailConfirmed)
                {
                    lblEmailError.Text = "Email address has already been confirmed";
                    lblEmailError.Visible = true;
                    return false;
                }
            }

            return true;
        }

        protected void btnSendConfirmationCode_Click(object sender, EventArgs e)
        {
            // Validation
            lblEmailError.Visible = false;
            lblConfirmationCodeError.Visible = false;
            lblInformation.Visible = false;
            if (!EmailIsValid())
            {
                return;
            }

            // Send an email to the user with a confirmation code so that they can confirm
            // their email address
            var userProperties = Functions.GetDatabaseDataContext()
                .Users
                .Where(u => u.Email.ToLower() == txtEmail.Text.Trim().ToLower())
                .Select(u => new { u.Email, u.EmailConfirmationCode })
                .Single();
            WebsiteEmail.SendEmailToConfirmEmailAddressPlainText(userProperties.Email, userProperties.EmailConfirmationCode);

            // Display the information label
            btnSendConfirmationCode.Visible = false;
            lblInformation.Visible = true;
        }

        private bool ConfirmationCodeIsValid()
        {
            // Required
            if (txtConfirmationCode.Text.Trim().Length == 0)
            {
                lblConfirmationCodeError.Text = "An entry is required";
                lblConfirmationCodeError.Visible = true;
                return false;
            }

            // Max length
            int maxLength = typeof(User).GetProperties()
                .Where(p => p.Name.ToLower() == "emailconfirmationcode")
                .Select(p => Functions.GetColumnSize((ColumnAttribute)p.GetCustomAttributes(typeof(ColumnAttribute), false).First()))
                .First();
            if (txtConfirmationCode.Text.Trim().Length > maxLength)
            {
                lblConfirmationCodeError.Text = String.Format("The entry cannot be more than {0} characters", maxLength);
                lblConfirmationCodeError.Visible = true;
                return false;
            }

            return true;
        }

        protected void btnCancel_Click(object sender, EventArgs e)
        {
            // Go back a page
            Response.Redirect(Request.UrlReferrer.ToString());
        }
    }
}